package PL.prac2;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class analex {
	
	private Alfabeto c;
	private Tokens t;
	private Integer bloque;
	private int numbloque;
	private Stack<Integer> inibloque;
	private List<encontrado> Tencontrados;
	
	public analex () {
		bloque = 0;
		numbloque = 0;
		inibloque = new Stack<Integer>();
		Tencontrados = new ArrayList<encontrado>();
	}
	
	public analex(Alfabeto a, Tokens x) {
		bloque = 0;
		numbloque = 0;
		inibloque = new Stack<Integer>();
		c = a;
		x = t;
	}
	
	//Lee los ficheros de los caracteres e identificadores
	//y coloca la informacion en sus objetos correspondientes.
	
	public void LeerEntradas() throws IOException {
		File carac = new File("caracteres.txt");
		File identif = new File("identificadores.txt");
		//Leemos el primer fichero y lo metemos en un string
		String linea;
		StringWriter aux = new StringWriter();
		FileReader fr = new FileReader (carac);
		BufferedReader br = new BufferedReader(fr);
		while((linea = br.readLine())!=null)
			aux.write(linea+"\n");
		c = new Alfabeto (aux.toString());
		br.close();
		fr.close();
		//Leemos el segundo fichero y lo metemos en un string
		StringWriter aux2 = new StringWriter();
		FileReader fr2 = new FileReader (identif);
		BufferedReader br2 = new BufferedReader(fr2);
		String linea2;
		while((linea2 = br2.readLine())!=null) {
			aux2.write(linea2+"\n");
		}
		t = new Tokens (aux2.toString());
		br2.close();
		fr2.close();
	}
	
	
	//Comprueba todos los caracteres, al igual que sus bloques.
	public boolean ComprobarCaracteres(String linea, int pos) {
	
		for (int i = 0; i<linea.length(); i++){
			if (!c.EnAlfabeto(linea.charAt(i))) {
				System.out.println("Caracter incorrecto\" " + linea.charAt(i) + "\" en la linea " + pos + " posicion " + i);
				return false;
			}
			if (linea.charAt(i) == '{') {
				inibloque.push(pos);
				bloque++;
			}
			if (linea.charAt(i) == '}') {
				if (inibloque.empty()) {
					System.out.println("Error: Se ha cerrado un bloque que no se ha abierto");
					return false;
				}
				int x = inibloque.pop();
				bloque--;
				System.out.println("Encontrado el bloque numero " + numbloque + " de nivel " + bloque + " desde la linea " + x + " hasta la linea " + pos + ".");
				numbloque++;
			}
		}
		return true;
	}
	
	
	public int encontrarpalabra(String palabra) {
		int indice = 0;
		boolean encontrado = false;
		if (!Tencontrados.isEmpty()){
			for (indice = 0; indice <Tencontrados.size(); indice++) {
				String aux = Tencontrados.get(indice).getPalabra();
				if (aux.equals(palabra)){
					encontrado = true;
					break;
				}
			}
			if (!encontrado) {
				return -1;
			}
			return indice;
		}
		return -1;
	}
	
	//Comprueba si la entrada tiene palabras reservadas.
	public void ComprobarPalabras(String linea, int pos) {
		String palabra = "";
		for (int i = 0; i < linea.length(); i++){
			if ((linea.charAt(i) != ' ') && (linea.charAt(i)!= '\t') && (linea.charAt(i)!= ';') 
					&& (linea.charAt(i) != '(') && (linea.charAt(i) != ')')){
				palabra = palabra + linea.charAt(i);
			}
			else {
				palabra = "";
			}
			if (t.EnToken(palabra.toString())) {
				if (encontrarpalabra(palabra.toString())!= -1){
					Tencontrados.get(encontrarpalabra(palabra.toString())).nuevo(pos);
				}
				else {
					encontrado a = new encontrado(palabra.toString());
					Tencontrados.add(a);
					Tencontrados.get(encontrarpalabra(palabra.toString())).nuevo(pos);
				}
				//Tencontrados.add(palabra.toString());
				//System.out.println("Encontrada palabra reservada \"" + palabra.toString() + "\" en la linea " + pos);
			}
		}
	}
	
	//Lee el fichero de entrada y comprueba simbolos y caracteres.
	public void Analizador() throws IOException {
		LeerEntradas();
		//File entrada = new File("entrada.java");
		File entrada = new File("src/main/java/PL/prac2/analex.java");
		String linea;
		FileReader fr = new FileReader (entrada);
		BufferedReader br = new BufferedReader(fr);
		boolean correcto = true;
		int j = 0;
		while((linea = br.readLine())!=null){
			if (!ComprobarCaracteres(linea,j)) {
				correcto = false;
				break;
			}
			if (correcto){
				ComprobarPalabras(linea,j);
			}
			j++;
		}
		if (correcto) {
			System.out.println("Se han encontrado las siguientes palabras reservadas: ");
			for (int i = 0; i < Tencontrados.size()-1; i++) {
				Tencontrados.get(i).visualizarlista();
			}
		}
		fr.close();
		br.close();
		
	}
		
	public static void main(String[] args) throws IOException {
		analex a = new analex();
		a.Analizador();
	}
}

